/*
 * @Author: Colin Dai
 * @Date: 2022-04-29 21:13:56
 * @LastEditors: Colin Dai
 * @LastEditTime: 2022-05-09 22:39:36
 * @FilePath: \intelligent-trash\src\main.ino
 * @Description: 
 * dailianzheng@163.com
 * Copyright (c) 2022 by Colin.Dai, All Rights Reserved. 
 */

#include "ai-audio.h"
#include "servo_ctrl.h"
#include "wheel_ctrl.h"
#include "dist_detect.h"

/* 时间相关函数
unsigned long micros(); //返回微秒为单位系统时间
unsigned long millis(); //返回毫秒为单位系统时间
void delay(uint32_t); //设置毫秒级延时
void delayMicroseconds(uint32_t us); //设置微秒级延时
*/


/**
 * @brief 全局变量定义
 * 
 */

#define VERSION    "1.5"

#define TURN_DELAY  800000  //转向持续时间
#define ASK_DELAY 500 //开盖延时说问垃圾类型
#define SONG_DELAY 500 //关盖延时说儿歌时间时间


boolean g_isForward = false; //是否前进
boolean g_isTurn = false; //是否转向或倒退

unsigned long g_last_turn_MS = 0; //上一次转向时刻

/**
 * @brief 初始化
 * @param {*}
 * @return {*}
 */
void setup() 
{
  
  //系统打印串口
  Serial.begin(115200);

  //打印版本号
  Serial.print("VERSION:");Serial.println(VERSION);

  //初始化AI语音模块
  init_AI_audio();

  //初始化舵机
  init_servo();

  //初始化底盘控制
  init_wheel();

  //初始化距离探测
  init_detect();

  //延时等待系统初始化
  delay(1500); 
}


/**
 * @brief 主循环
 * @param {*}
 * @return {*}
 */
void loop() 
{  
  
  //检测语音
  AUDIO_RECV_CMD_TYPE cmd = check_audio_cmd();

  switch (cmd)
  {
  case CMD_R_A_NULL:
    //无需做事
    break;
  case CMD_R_A_THROW://要扔垃圾
  case CMD_R_A_FRONT://向前走 
    Serial.println("Received CMD_R_A_THROW or CMD_R_A_FRONT !");    
    if(g_isForward || g_isTurn)
    {
        stop_car();
    }
    car_forward();
    g_isForward = true;
    break;
  case CMD_R_A_LEFT://向左走 
    Serial.println("Received CMD_R_A_LEFT !");   
    //如果在运动，先停下车
    if(g_isForward || g_isTurn)
    {
        stop_car();
    }
    car_left();
    g_isTurn = true; 
    g_last_turn_MS = micros();
    break;
  case CMD_R_A_RIGHT://向右走 
    Serial.println("Received CMD_R_A_RIGHT !");  
    //如果在运动，先停下车
    if(g_isForward || g_isTurn)
    {
        stop_car();
    }
    car_right();
    g_isTurn = true;
    g_last_turn_MS = micros();
    break;
  case CMD_R_A_BACK://向后走 
    Serial.println("Received CMD_R_A_BACK !");  
    //如果在运动，先停下车
    if(g_isForward || g_isTurn)
    {
        stop_car();
    }
    car_backward();
    g_isTurn = true;  
    g_last_turn_MS = micros(); 
    break;
  case CMD_R_A_STOP://停止
    Serial.println("Received CMD_R_A_STOP !");  
    stop_car();
    break;
  case CMD_R_A_OPEN://开盖
    Serial.println("Received CMD_R_A_OPEN !");  
    //如果在运动，先停下车
    if(g_isForward || g_isTurn)
    {
        stop_car();
    }
    open_trash();
    //发出语音询问垃圾类型
    delay(ASK_DELAY);
    send_audio_cmd(CMD_S_A_ASKTYPE);
    break;
  case CMD_R_A_CLOSE://关盖
    Serial.println("Received CMD_R_A_CLOSE !");  
    //如果在运动，先停下车
    if(g_isForward || g_isTurn)
    {
        stop_car();
    }
    close_trash();

    //延时，说儿歌
    if(g_isForward == false && g_isTurn == false)
    {
        delay(SONG_DELAY);
        send_audio_cmd(CMD_S_A_SONG);
    }    
    break;
  default:
    break;
  }

  //判断是否有阻碍，然后求助
  if(g_isForward)
  {
     boolean b = can_forward();

     if (!b)
     {
       //有障碍，停止车辆
       Serial.println("Can not forward to stop car!");  
       stop_car();
       send_audio_cmd(CMD_S_A_HELP);
     }
  }

  //转弯只循序持续一段时间
  unsigned long curMS =  micros();
  if (g_isTurn)
  {
    /*
    Serial.println(curMS);  
    Serial.println(g_last_turn_MS);  
    */
    if((curMS - g_last_turn_MS) > TURN_DELAY)
    {
      Serial.println("Timeout to stop car!");  
      stop_car();
    }
  }  
}

/**
 * @brief 打开垃圾桶盖子
 * @param {*}
 * @return {*}
 */
void open_trash()
{
  
  adjust_servo(120);
   //等待执行完毕
  delay(100); 
  Serial.println("open_trash...");
}

/**
 * @brief 关闭垃圾桶
 * @param {*}
 * @return {*}
 */
void close_trash()
{
  
  adjust_servo(0);
   //等待执行完毕
  delay(100);
  Serial.println("close_trash...");
}

/**
 * @brief 停下车
 * @param {*}
 * @return {*}
 */
void stop_car()
{
  car_stop();
  g_isForward = false;
  g_isTurn = false;
}




